import {
  AbilityBuilder,
  createMongoAbility,
  InferSubjects,
  MongoAbility,
} from '@casl/ability';
import { User, UserRole } from '@/user/schemas/user.schema';
import { Work } from '@/work/schemas/work.schema';
import { Channel } from '@/work/schemas/channel.schema';
import { Types } from 'mongoose';

export type Actions =
  | 'create'
  | 'read'
  | 'update'
  | 'delete'
  | 'publish'
  | 'manage';
export type Subjects =
  | InferSubjects<typeof User | typeof Work | typeof Channel>
  | 'Work'
  | 'User'
  | 'Channel'
  | 'all';
export type AppAbility = MongoAbility<[Actions, Subjects]>;

// @Injectable()
export class CaslAbilityFactory {
  // TODO 这里ts类型
  defineRoles(user: {
    _id: string | Types.ObjectId;
    id: string;
    role: UserRole;
  }) {
    const { can, build } = new AbilityBuilder<AppAbility>(createMongoAbility);
    if (user?.role === 'admin') {
      can('manage', 'all');
    } else {
      // normal login user
      // users 只能读取自己的信息，以及更新特殊的字段
      can('read', 'User', { id: user._id });
      can('update', 'User', ['nickName', 'pickure'], {
        id: user._id,
      });

      // works, 可以创建，然后可以更新和删除自己的 Work
      can('create', 'Work', ['title', 'desc', 'content', 'coverImg']);
      can('read', 'Work', { user: user._id });
      can('update', 'Work', ['title', 'desc', 'content', 'coverImg'], {
        user: user._id,
      });
      can('delete', 'Work', { user: user._id });
      can('publish', 'Work', { user: user._id });

      // //   channels 创建，更新，删除，属于自己的
      can('create', 'Channel', ['channelName', 'workId']);
      can('read', 'Channel', { user: user._id });
      can('update', 'Channel', ['channelName'], { user: user._id });
      can('delete', 'Channel', ['channelName'], { user: user._id });
    }
    return build();
  }
}
